﻿Imports System.IO
Imports System.Runtime.Serialization.Formatters.Binary

Namespace Load

    ''' <summary>
    ''' クエリ処理ができるリスト
    ''' </summary>
    ''' <typeparam name="T"></typeparam>
    ''' <remarks>ラッパークラス</remarks>
    Public Class QueryableList(Of T)
        Implements IFromQueryRoot(Of QueryableList(Of T))
        Implements ICloneableExporter(Of T)

        Public Shared Function Create(r As ModelLoader, source As IList(Of T)) As QueryableList(Of T)
            'NEW の記述をしたくない場合用。（NEWをすると変数で受ける必要がありますが、この関数なら受けなくてもOK）
            '2層目以降を読み込むための窓口。通常はあまり使用しない。
            Return New QueryableList(Of T)(r, source)
        End Function

        ''' <summary>
        ''' コンストラクタ
        ''' </summary>
        ''' <param name="r">モデルローダー</param>
        ''' <param name="source">起点となるオブジェクト</param>
        ''' <remarks></remarks>
        Public Sub New(r As ModelLoader, source As T)
            'List型に型変換
            Dim lstType As Type = GetType(List(Of )).MakeGenericType({GetType(T)})
            Dim lst As IList = Activator.CreateInstance(lstType)
            lst.Add(source)

            _loader = r
            _innerList = lst

            r.ResetQueryType()
        End Sub

        ''' <summary>
        ''' コンストラクタ
        ''' </summary>
        ''' <param name="r">モデルローダー</param>
        ''' <param name="source">起点となるオブジェクトリスト</param>
        ''' <remarks></remarks>
        Public Sub New(r As ModelLoader, source As IList(Of T))
            _loader = r
            _innerList = source

            r.ResetQueryType()
        End Sub

        ''' <summary>
        ''' コンストラクタ
        ''' </summary>
        ''' <param name="r">モデルローダー</param>
        ''' <param name="source">起点となるオブジェクトページリスト</param>
        ''' <remarks></remarks>
        Public Sub New(r As ModelLoader, source As PageList(Of T))
            _loader = r
            _innerList = source

            r.ResetQueryType()
        End Sub

        Private _loader As ModelLoader
        ''' <summary>
        ''' モデルローダー
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Friend ReadOnly Property Loader As ModelLoader
            Get
                Return _loader
            End Get
        End Property

        Private _innerList As Object
        ''' <summary>
        ''' 起点となるオブジェクト
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Friend ReadOnly Property InnerList As IList(Of T)
            Get
                Return DirectCast(_innerList, IList(Of T))
            End Get
        End Property

#Region "IQueryRoot"
        Public Sub ResetQueryType() Implements IQueryRoot(Of QueryableList(Of T)).ResetQueryType
            Me.Loader.ResetQueryType()
        End Sub

        Public Function Batch() As QueryableList(Of T) Implements IQueryRoot(Of QueryableList(Of T)).Batch
            Me.Loader.Batch()
            Return Me
        End Function

        Public Function Iterate() As QueryableList(Of T) Implements IQueryRoot(Of QueryableList(Of T)).Iterate
            Me.Loader.Iterate()
            Return Me
        End Function

        Public Function Cascade(level As Integer) As QueryableList(Of T) Implements IQueryRoot(Of QueryableList(Of T)).Cascade
            Me.Loader.Cascade(level)
            Return Me
        End Function

        Public Function FullCascade() As QueryableList(Of T) Implements IQueryRoot(Of QueryableList(Of T)).FullCascade
            Me.Loader.FullCascade()
            Return Me
        End Function

        Public Function IncludeOuter() As QueryableList(Of T) Implements IQueryRoot(Of QueryableList(Of T)).IncludeOuter
            Me.Loader.IncludeOuter()
            Return Me
        End Function

        Public Function InnerOnly() As QueryableList(Of T) Implements IQueryRoot(Of QueryableList(Of T)).InnerOnly
            Me.Loader.InnerOnly()
            Return Me
        End Function

        Public Function From(Of SelectT)() As Query(Of SelectT) Implements IFromQueryRoot(Of Kairyu.Load.QueryableList(Of T)).From
            Return Me.Loader.From(Of SelectT)()
        End Function
#End Region

#Region "ICloneableExporter"
        Public Function Clone() As ICloneableExporter(Of T) Implements ICloneableExporter(Of T).Clone
            Return CloneableExporter.Clone(Me.InnerList)
        End Function

        Public Function ToArray() As T() Implements ICloneableExporter(Of T).ToArray
            Return Me.InnerList.ToArray
        End Function

        ''' <summary>
        ''' アイテムを取得します。存在しない場合や、アイテム数が1以外の場合はNothingが返されます。
        ''' </summary>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function ToItem() As T Implements ICloneableExporter(Of T).ToItem
            If Me.InnerList.Count <> 1 Then Return Nothing
            Return Me.InnerList.First
        End Function

        Public Function ToList() As System.Collections.Generic.List(Of T) Implements ICloneableExporter(Of T).ToList
            Return Me.InnerList.ToList
        End Function
#End Region

        Public Function ToPageList() As PageList(Of T)
            Return DirectCast(_innerList, PageList(Of T))
        End Function

    End Class

End Namespace